package br.com.vpsa.previdordevendas.model.service.impl;

import java.util.Calendar;
import java.util.List;

import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.Query;
import javax.persistence.TypedQuery;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import br.com.vpsa.previdordevendas.model.adapter.PedidoAdapter;
import br.com.vpsa.previdordevendas.model.entity.FaturamentoMensal;
import br.com.vpsa.previdordevendas.model.entity.HistoricoConsolidacao;
import br.com.vpsa.previdordevendas.model.entity.JsonPedidos;
import br.com.vpsa.previdordevendas.model.entity.Pedido;
import br.com.vpsa.previdordevendas.model.pojo.PedidoPojo;
import br.com.vpsa.previdordevendas.model.service.ConsolidadorPedidosService;
import br.com.vpsa.previdordevendas.model.util.CalendarUtils;
import br.com.vpsa.previdordevendas.model.util.HttpUtils;
import br.com.vpsa.previdordevendas.model.util.JsonUtils;

import com.google.gson.reflect.TypeToken;

@Service
public class ConsolidadorPedidosServiceImpl implements ConsolidadorPedidosService {

    @PersistenceContext
    private EntityManager em;
    
    @Autowired
    private PedidoAdapter pedidoAdapter;
    
    @Override
    @Transactional
	public boolean verificarConsolidacao( String base )
    {
		HistoricoConsolidacao ultimaConsolidacao = em.find(HistoricoConsolidacao.class, base);
        boolean result = true;
		
		if ( ultimaConsolidacao != null ) 
		{
			if( CalendarUtils.getMesAtual() > ultimaConsolidacao.getData().get(Calendar.MONTH) ||
				CalendarUtils.getAnoAtual() > ultimaConsolidacao.getData().get(Calendar.YEAR))
			{
				result = false;
			}
        }
		else 
		{
			result = false;
		}
		
		return result;
	}
   
    @Override
    @Transactional
    public void salvarPedidosPojo( String base )
    {
    	apagarPedidoPorBase(base);
    	
		for ( JsonPedidos jsonPedidos : listarJsonPedidos(base) )
		{
			List<PedidoPojo> pedidosPojo = JsonUtils.getList(jsonPedidos.getJson(), new TypeToken<List<PedidoPojo>>(){}.getType());
				
			for( PedidoPojo pedidoPojo : pedidosPojo )
			{
				Pedido pedido = pedidoAdapter.pedidoPojoToPedido(pedidoPojo, jsonPedidos.getIdEntidade(), base);

				em.merge(pedido);
			}
		}
    }

	@Override
	@Transactional
	public int salvarJsonPedidos(long idEntidade, int inicio, int quantidade, String base) 
	{
		if( inicio == 0 ){
			apagarJsonPedidosPorBaseEEntidade( base, idEntidade);
		}
		
		String json = HttpUtils.requestGetHttpsAutenticada("https://www.vpsa.com.br/apps/api/pedidos?entidades="+ 
				idEntidade +"&inicio="+ inicio +"&quantidade="+ quantidade);
		
		JsonPedidos jsonPedidos = new JsonPedidos();
		
		jsonPedidos.setBase(base);
		jsonPedidos.setIdEntidade(idEntidade);
		jsonPedidos.setJson(json);
		
		em.persist(jsonPedidos);
		
		List<PedidoPojo> pedidosPojo = JsonUtils.getList(json, new TypeToken<List<PedidoPojo>>(){}.getType());
		
		return pedidosPojo.size(); 
	}
	
	@Override
	@Transactional
	public void sumarizarPedidos(String base) 
	{
		apagarFaturamentoMensalPorBase(base);
		
		String hql = "SELECT new br.com.vpsa.previdordevendas.model.entity.FaturamentoMensal(p.idEntidade, p.ano, p.mes, sum(p.valor)) FROM Pedido p " +
				 " where p.base = :base " +
				 " group by p.idEntidade, p.ano, p.mes " +
				 " order by p.mes";

		TypedQuery<FaturamentoMensal> query = em.createQuery(hql, FaturamentoMensal.class);
		query.setParameter("base", base);
		
		for( FaturamentoMensal faturamentoMensal : query.getResultList() ){
			faturamentoMensal.setBase(base);
			em.persist(faturamentoMensal);
		}
		
		HistoricoConsolidacao ultimaConsolidacao = em.find(HistoricoConsolidacao.class, base);
		if( ultimaConsolidacao == null ){
			ultimaConsolidacao = new HistoricoConsolidacao(base,Calendar.getInstance());
		}
		else{
			ultimaConsolidacao.setData(Calendar.getInstance());
		}
		
		em.merge(ultimaConsolidacao);
	}
	
	@Override
	public List<JsonPedidos> listarJsonPedidos(String base) 
	{
		String hql = "from JsonPedidos j where j.base = :base";
		
		TypedQuery<JsonPedidos> query = em.createQuery(hql, JsonPedidos.class);
		query.setParameter("base", base);
		
		return query.getResultList();
	}
	
	private void apagarPedidoPorBase( String base )
	{
		String hql = "delete from Pedido p where p.base = :base";
		
		Query query = em.createQuery(hql);
		query.setParameter("base", base);
		
		query.executeUpdate();		
	}

	private void apagarJsonPedidosPorBaseEEntidade( String base, long idEntidade )
	{
		String hql = "delete from JsonPedidos j where j.base = :base and j.idEntidade = :idEntidade";
		
		Query query = em.createQuery(hql);
		query.setParameter("base", base);
		query.setParameter("idEntidade",idEntidade);
		
		query.executeUpdate();		
	}

	private void apagarFaturamentoMensalPorBase( String base )
	{
		String hql = "delete from FaturamentoMensal f where f.base = :base";
		
		Query query = em.createQuery(hql);
		query.setParameter("base", base);
		
		query.executeUpdate();		
	}

	

}
